﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;

namespace CLM.Gestao.Relatorio
{
    public enum TipoRelatorio
    {
        Simples
    }

    public class Excel<T>
    {
        #region metodos e propriedades

        private static int LinhaInicial { get; set; }
        private static int ColunaInicial { get; set; }

        private static TipoRelatorio _TipoRelatorio;
        public static TipoRelatorio TipoRelatorio
        {
            get { return _TipoRelatorio; }
            set
            {
                _TipoRelatorio = value;
                if (_TipoRelatorio == TipoRelatorio.Simples)
                {
                    LinhaInicial = 1;
                    ColunaInicial = 2;
                }
            }
        }

        private static Excel.Application NewAppication = null;
        private static Excel._Workbook NewWorkbook = null;
        private static Excel._Worksheet NewWorksheet = null;

        #endregion

        #region Construtor

        public Excel()
        {
            TipoRelatorio = TipoRelatorio.Simples;
        }

        #endregion

        public static void Gerar(List<T> pItens, string[] pCabecalho, string pTitulo, string pSheetName, Excel.Application pApplication)
        {
            Gerar(pItens, null, pCabecalho, pTitulo, pSheetName, pApplication);
        }

        public static void Gerar(List<T> pItens, List<string> pListaCampos, string[] pCabecalho, string pTitulo, string pSheetName, Excel.Application pApplication)
        {
            int LinhaAtual;
            int ColunaAtual;
            int ColunaFinal = pCabecalho.Length + 1;

            NewAppication = pApplication;
            NewWorkbook = pApplication.ActiveWorkbook;

            GeraPlanilha(pSheetName);
            NewWorksheet.Application.ScreenUpdating = false;
            //Insere o titulo da exportação e realiza o merge das celulas
            NewWorksheet.Cells[LinhaInicial, ColunaInicial] = pTitulo;
            //if (ColunaFinal <= 18)
            NewWorksheet.Range[NewWorksheet.Cells[LinhaInicial, 1], NewWorksheet.Cells[LinhaInicial, ColunaFinal + 1]].Merge();
            //else
            //    NewWorksheet.Range[NewWorksheet.Cells[LinhaInicial, 1], NewWorksheet.Cells[LinhaInicial, 19]].Merge();

            LinhaAtual = LinhaInicial + 2;
            ColunaAtual = ColunaInicial;

            //Insere o cabeçalho da lista
            foreach (var Titulo in pCabecalho)
            {
                NewWorksheet.Cells[LinhaAtual, ColunaAtual] = Titulo;
                ColunaAtual++;
            }

            ColunaAtual = ColunaInicial;
            LinhaAtual++;

            //Insere os valores da lista passada
            var props = typeof(T).GetProperties();

            Type t = typeof(T);
            PropertyInfo pi;
            string tipo;

            foreach (var item in pItens)
            {
                foreach (var prop in props)
                {
                    if (pListaCampos == null || pListaCampos.Contains(prop.Name))
                    {
                        pi = t.GetProperty(prop.Name);
                        tipo = pi.PropertyType.ToString();

                        if (tipo.Contains("Decimal") || tipo.Contains("Double"))
                            NewWorksheet.Cells[LinhaAtual, ColunaAtual] = string.Format("{0:C}", prop.GetValue(item, null));
                        //else if (tipo.Contains("Decimal"))
                        //    NewWorksheet.Cells[LinhaAtual, ColunaAtual] = string.Format("{0:C}", prop.GetValue(item, null));
                        else
                            NewWorksheet.Cells[LinhaAtual, ColunaAtual] = prop.GetValue(item, null);


                        ColunaAtual++;
                    }
                }
                ColunaAtual = ColunaInicial;
                LinhaAtual++;
            }

            FormataPlanilha(NewWorksheet, LinhaAtual - 1, ColunaFinal);
            NewAppication.ActiveWindow.DisplayGridlines = false;
            NewAppication.ScreenUpdating = true;
        }

        private static void FormataPlanilha(Excel._Worksheet pWorksheet, int pLinhaFinal, int pColunaFinal)
        {
            pWorksheet.Range[pWorksheet.Cells[1, 1], pWorksheet.Cells[1, 1]].ColumnWidth = 1;

            pWorksheet.Range[pWorksheet.Cells[1, 1], pWorksheet.Cells[1, 1]].RowHeight = 100;
            pWorksheet.Range[pWorksheet.Cells[2, 1], pWorksheet.Cells[pLinhaFinal, 1]].RowHeight = 15;
            pWorksheet.Range[pWorksheet.Cells[(pLinhaFinal + 1), 1], pWorksheet.Cells[(pLinhaFinal + 1), 1]].RowHeight = 100;

            //Formata o Titulo
            var RangeAtual = pWorksheet.Range[pWorksheet.Cells[1, 1], pWorksheet.Cells[1, 1]];
            RangeAtual.Interior.Pattern = Excel.XlPattern.xlPatternLinearGradient;
            RangeAtual.Interior.Gradient.Degree = 90;
            RangeAtual.Interior.Gradient.ColorStops.Clear();
            RangeAtual.Interior.Gradient.ColorStops.Add(0).Color = System.Drawing.Color.FromArgb(31, 73, 125);
            RangeAtual.Interior.Gradient.ColorStops.Add(1).Color = System.Drawing.Color.FromArgb(190, 190, 190);

            RangeAtual.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
            RangeAtual.VerticalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
            RangeAtual.Font.Bold = false;
            RangeAtual.Font.Size = 40;
            RangeAtual.Font.Color = 16777215;

            //Formata os dados
            RangeAtual = pWorksheet.Range[pWorksheet.Cells[2, 1], pWorksheet.Cells[pLinhaFinal, pColunaFinal + 1]];
            RangeAtual.Interior.Color = System.Drawing.Color.FromArgb(190, 190, 190);

            RangeAtual = pWorksheet.Range[pWorksheet.Cells[3, ColunaInicial], pWorksheet.Cells[pLinhaFinal, pColunaFinal]];
            RangeAtual.Interior.Pattern = Excel.XlPattern.xlPatternNone;
            RangeAtual.Borders[Excel.XlBordersIndex.xlEdgeLeft].Color = System.Drawing.Color.FromArgb(0, 0, 0);
            RangeAtual.Borders[Excel.XlBordersIndex.xlEdgeTop].Color = System.Drawing.Color.FromArgb(0, 0, 0);
            RangeAtual.Borders[Excel.XlBordersIndex.xlEdgeRight].Color = System.Drawing.Color.FromArgb(0, 0, 0);
            RangeAtual.Borders[Excel.XlBordersIndex.xlEdgeBottom].Color = System.Drawing.Color.FromArgb(0, 0, 0);

            RangeAtual.AutoFilter(1, Type.Missing, Excel.XlAutoFilterOperator.xlAnd, Type.Missing, true);
            RangeAtual.EntireColumn.AutoFit();

            //Formata o Cabecalho
            RangeAtual = pWorksheet.Range[pWorksheet.Cells[3, ColunaInicial], pWorksheet.Cells[3, pColunaFinal]];
            RangeAtual.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
            RangeAtual.WrapText = true;
            RangeAtual.Font.Bold = true;
            RangeAtual.Interior.Color = System.Drawing.Color.FromArgb(54, 96, 146);
            RangeAtual.Borders.Color = System.Drawing.Color.FromArgb(255, 255, 255);
            RangeAtual.Font.Color = 16777215;

            //formata o rodapé
            RangeAtual = pWorksheet.Range[pWorksheet.Cells[(pLinhaFinal + 1), 1], pWorksheet.Cells[(pLinhaFinal + 1), pColunaFinal + 1]];
            RangeAtual.Interior.Pattern = Excel.XlPattern.xlPatternLinearGradient;
            RangeAtual.Interior.Gradient.Degree = 90;
            RangeAtual.Interior.Gradient.ColorStops.Clear();
            RangeAtual.Interior.Gradient.ColorStops.Add(0).Color = System.Drawing.Color.FromArgb(190, 190, 190);
            RangeAtual.Interior.Gradient.ColorStops.Add(1).Color = System.Drawing.Color.FromArgb(255, 255, 255);
            RangeAtual.EntireColumn.AutoFit();

            pWorksheet.Range[pWorksheet.Cells[(pLinhaFinal + 2), 1], pWorksheet.Range[pWorksheet.Cells[(pLinhaFinal + 2), 1], pWorksheet.Cells[(pLinhaFinal + 2), 1]].End[Excel.XlDirection.xlDown]].EntireRow.Hidden = true;
            pWorksheet.Range[pWorksheet.Cells[1, (pColunaFinal + 2)], pWorksheet.Range[pWorksheet.Cells[1, (pColunaFinal + 2)], pWorksheet.Cells[1, (pColunaFinal + 2)]].End[Excel.XlDirection.xlToRight]].EntireColumn.Hidden = true;

            NewAppication.ActiveWindow.Zoom = 80;
            pWorksheet.Range["A1"].Select();
        }

        private static void GeraPlanilha(string pSheetName)
        {
            bool WorkflowReportSheet = false;

            foreach (Microsoft.Office.Interop.Excel._Worksheet worksheet in NewWorkbook.Worksheets)
                if (worksheet.Name == pSheetName)
                {
                    NewWorksheet = worksheet;
                    NewWorksheet.Range["A1:ZZ10000"].Clear();
                    WorkflowReportSheet = true;
                    break;
                }

            if (WorkflowReportSheet == false)
            {
                NewWorksheet = (Microsoft.Office.Interop.Excel._Worksheet)NewAppication.Worksheets.Add();
                NewWorksheet.Name = pSheetName;
            }
            NewWorksheet.Select();
            NewWorksheet.Range["A1"].Select();
        }
    }
}